#ifndef	MACROS_H
#define MACROS_H

#include "sysdef.h"
#include "types.h"

/* 7.18.2.1  Limits of exact-width integer types */
#ifndef INT8_MIN
#   define INT8_MIN (-128) 
#endif

#ifndef INT16_MIN
#   define INT16_MIN (-32768)
#endif

#ifndef INT32_MIN
#define INT32_MIN (-2147483647 - 1)
#endif

#ifndef INT64_MIN
#   ifdef __GNUC__
#        define INT64_MIN  (-9223372036854775807LL - 1)
#   else
#       define INT64_MIN  (-9223372036854775807i64 - 1)
#   endif
#endif

#ifndef INT8_MAX
#   define INT8_MAX 127
#endif

#ifndef INT16_MAX
#   define INT16_MAX 32767
#endif

#ifndef INT32_MAX
#   define INT32_MAX 2147483647
#endif

#ifndef INT64_MAX
#   ifdef __GNUC__
#       define INT64_MAX 9223372036854775807LL
#   else
#       define INT64_MAX 9223372036854775807i64
#   endif
#endif

#ifndef UINT8_MAX
#   define UINT8_MAX 0xff /* 255U */
#endif

#ifndef UINT16_MAX
#   define UINT16_MAX 0xffff /* 65535U */
#endif

#ifndef UINT32_MAX
#   define UINT32_MAX 0xffffffff  /* 4294967295U */
#endif

#ifndef UINT64_MAX
#   ifdef __GNUC__
#       define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
#   else
#       define UINT64_MAX 0xffffffffffffffffui64 /* 18446744073709551615ULL */
#   endif
#endif


#if defined(WIN32) || defined(WINDOWS)

typedef unsigned int ErrorCode;

#else

typedef INT32  ErrorCode;
#   define _strnicmp strncasecmp
#   define _stricmp strcasecmp
#   define _wcsicmp wcscasecmp
#   define _wcsnicmp wcsncasecmp

#endif

#if defined(WIN32) || defined(WINDOWS)

#else
#   if defined(_UNICODE) || defined(UNICODE)
#       define __TEXT(quote) L##quote     
#   else
#       define __TEXT(quote) quote
#	endif
#   define TEXT(quote) __TEXT(quote)

#endif


/*
 * MF  - Macros which act as a Function, it return value
 * MP  - Macros which act as a Procedure,no value is returned
 * MCF - Macros which act as a Function for compatibility
 * MCP - Macros which act as a Procedure for compatibility
 * MC  - Macros which defined as constant value
 * MS  - Macros which defined as a control switch
*/

#if defined(WIN32) || defined(WINDOWS)
#   define _USER_BREAK_	__debugbreak() //{ do { __asm { int 3 }; } while (0); }
#else
#   undef FALSE
#   define FALSE               0

#   undef TRUE
#   define TRUE                1

#   define _USER_BREAK_ { do { asm ( "int $3;" ); } while(0); }
#endif

#define MC_NULLPTR_OF_(type) static_cast<type>(0)

#undef ASSERT
#define DEBUG_BREAK		_USER_BREAK_
#define RELEASE_BREAK	_USER_BREAK_

#if defined(NOASSERT)
#   define ASSERT_I(cond) \
    if(!(cond)) \
    { \
        _log_(LOG_FATAL, "ASSERT: %s:%u <%s>", __FILE__,__LINE__,#cond); \
    }

#   define ASSERT_I_2(cond,rst) \
    if((cond)) \
    { \
        rst = TRUE; \
    } \
    else \
    { \
        rst = FALSE; \
        _log_(LOG_FATAL, "ASSERT: %s:%u <%s>", __FILE__,__LINE__,#cond); \
    }

#else
#   define ASSERT_I(cond) \
    { \
        if(!(cond)) { _USER_BREAK_ } \
    }

#   define ASSERT_I_2(cond,rst) \
    { \
        if((cond)) \
        { \
            rst = TRUE; \
        } \
        else \
        { \
            rst = FALSE; \
            _USER_BREAK_ \
        } \
    }
#endif

#define ASSERT_RETURN(cond, ret) \
 { \
    BOOL _assert_b_; \
    ASSERT_I_2(cond, _assert_b_); \
    if(!_assert_b_) return ret; \
 }

#define ASSERT_RETURN_VOID(cond) \
 { \
    BOOL _assert_b_; \
    ASSERT_I_2(cond, _assert_b_); \
    if(!_assert_b_) return; \
 }

#define ASSERT(expression) \
            { do { if ( ! (expression) ) { RELEASE_BREAK; } } while(0); }

#define MF_ALIGN_SIZE(n) ((n+sizeof(void*)-1) & (~(sizeof(void*)-1)))
#define MP_SAFE_FREE(a)            do {if ((a)!= ((address_t)0)) {free(a); (a)=(address_t)0;}} while(0)
#define MP_SAFE_DELETE(a)          do {if ((a)!= ((address_t)0)) {delete(a); (a)=(address_t)0;}} while(0)
#define MP_SAFE_DELETE_CAST(t,a)          do {if ((a)!= ((address_t)0)) {delete((t*) (a)); (a)=(address_t)0;}} while(0)
#define MP_SAFE_DELETE_ARRAY(a)    do {if ((a)!= ((address_t)0)) {delete[] (a); (a)=(address_t)0;}} while(0)
#define MP_SAFE_DELETE_ARRAY_CAST(t,a)  do {if ((a)!= ((address_t)0)) {delete[] (t*)(a); (a)=(address_t)0;}} while(0)

#if defined(WIN32) || defined(WINDOWS)
#   define MCF_COUNT_OF _countof
#   define THREAD_ROUTINE_CALL     __stdcall

#else
#   define MCF_COUNT_OF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#   define THREAD_ROUTINE_CALL
#endif


#define DECLARE_SIMPLE_TYPE(T) \
    template <> struct _is_simple_type_<T> \
{ \
    static const bool value = true; \
};


#define MP_CHECK_RANGE_OO_RETURN(v,l,u,ret)   \
    {\
    if (((v)<=(l)) || ((v)>=(u))) return ret;\
    }
#define MP_CHECK_RANGE_OC_RETURN(v,l,u,ret)   \
 {\
 if (((v)<=(l)) || ((v)>(u))) return ret;\
 }
#define MP_CHECK_RANGE_CO_RETURN(v,l,u,ret)   \
 {\
 if (((v)<(l)) || ((v)>=(u))) return ret;\
 }
#define MP_CHECK_RANGE_CC_RETURN(v,l,u,ret)   \
 {\
 if (((v)<(l)) || ((v)>(u))) return ret;\
 }

#define MP_CHECK_RANGE_OO_VOID(v,l,u)   \
 {\
 if (((v)<=(l)) || ((v)>=(u))) return;\
 }
#define MP_CHECK_RANGE_OC_VOID(v,l,u)   \
 {\
 if (((v)<=(l)) || ((v)>(u))) return;\
 }
#define MP_CHECK_RANGE_CO_VOID(v,l,u)   \
 {\
 if (((v)<(l)) || ((v)>=(u))) return;\
 }
#define MP_CHECK_RANGE_CC_VOID(v,l,u)   \
 {\
 if (((v)<(l)) || ((v)>(u))) return;\
 }


/* MC_INVALID_SIZE */
#if !defined(MC_INVALID_SIZE)
#define MC_INVALID_SIZE ((size_t)-1)
#endif


#define M_DISABLE_COPY(Class) \
    Class(const Class &); \
    Class &operator=(const Class &);


#endif
